/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.wdb.websocket;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 *
 * @author vacoor
 */
@ServerEndpoint("/database")
public class DatabaseEndpoint {
    private static final Logger LOG = LoggerFactory.getLogger(DatabaseEndpoint.class);
    private Map<String, Connection> conns = new HashMap<String, Connection>();

    @OnOpen
    public void onOpen(final Session session) throws IOException {
        LOG.debug("Session {} open", session.getId());

    }

    /**
     * ID|Command[argument list]
     * @param message
     * @param session
     * @throws IOException
     */
    @OnMessage
    public void onMessage(String message, Session session) throws IOException, SQLException {
        RemoteEndpoint.Basic re = session.getBasicRemote();
        StringBuilder buffer = new StringBuilder(message);

        int i = buffer.indexOf("|");
        if (i < 0 || i == buffer.length() - 1) {
            re.sendText("[false, \"Invalid Command\"]");
            return;
        }

        String id = buffer.substring(0, i);
        String command = buffer.substring(i + 1);
        String[] args = new String[0];

        i = buffer.indexOf("[");
        if (-1 < i) { // should exists arguments
            if (0 == i || buffer.indexOf("]") != buffer.length() - 1) {
                re.sendText("[false, \"Invalid Command\"]");
                return;
            }
            command = buffer.substring(id.length() + 1, i);
            args = buffer.substring(i + 1, buffer.length() - 1).split("\\]\\[");
        }

        if (id.isEmpty()) {
            if ("NEW".equals(command)) {
                Connection conn = DriverManager.getConnection("jdbc:h2:mem:dataSource;DB_CLOSE_DELAY=-1", "sa", "");
                conns.put(UUID.randomUUID().toString(), conn);
                re.sendText(conn.getMetaData().getUserName());
                return ;
            } else if ("LOCAL".equals(command)) {
            }
        }

//        String s = cache.get(id);
//        if (s == null) {
            // don't exists database
            // invalid command
//            re.sendText("[false, \"Invalid Database ID\"]");
//            return;
//        }

        re.sendText(String.format("id:%s, command: %s, args: %s", id, command, Arrays.toString(args)));

        System.out.printf("id:%s, command: %s, args: %s", id, command, Arrays.toString(args));

        /**
         * ID|SCHEM
         * ID|TABS[SCHEM]
         * ID|COLS[TABS][SCHEM]
         * ID|VIEWS[SCHEM]
         * ----------------
         * ID|INDXS[SCHEM]
         * ID|FUNCS[SCHEM]
         * ID|PROCS[SCHEM]
         */
    }

    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        //
    }

    @OnError
    public void onError(Throwable ex, Session session) {
        LOG.warn("Session exception: {}", ex);

        if (session.isOpen()) {
            try {
                session.close();
            } catch (IOException e) {
                // ignore
            }
        }
    }
}
